package com.example.futureai.controller.chat;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.example.futureai.constants.Result;
import com.example.futureai.dto.ChatDto;
import com.example.futureai.dto.DocVtsDto;
import com.example.futureai.dto.News;
import com.example.futureai.dto.SendMsgDto;
import com.example.futureai.eum.ChatTYpe;
import com.example.futureai.po.ChatSessionRecord;
import com.example.futureai.po.UserSession;
import com.example.futureai.service.CharRecordService;
import com.example.futureai.service.ChatService;
import com.example.futureai.utils.ChatUtil;
import com.example.futureai.utils.TokenUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor;
import org.springframework.ai.chat.memory.InMemoryChatMemory;
import org.springframework.ai.ollama.OllamaChatModel;
import org.springframework.ai.tool.ToolCallbackProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.codec.ServerSentEvent;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;

import java.util.ArrayList;
import java.util.List;

import static org.springframework.ai.chat.client.advisor.AbstractChatMemoryAdvisor.CHAT_MEMORY_CONVERSATION_ID_KEY;
import static org.springframework.ai.chat.client.advisor.AbstractChatMemoryAdvisor.CHAT_MEMORY_RETRIEVE_SIZE_KEY;

/**
 * @ClassName: ChatAiController
 * @Description:
 * @Author: YourName
 * @Date: 2025/1/23
 */

@RestController
@Slf4j
@RequestMapping("/openai")
public class ChatAiController {
    @Autowired
    private ChatService chatService;

    @Autowired
    private CharRecordService charRecordService;


    @Autowired
    private OllamaChatModel ollamaChatModel;
    @Autowired
    private ToolCallbackProvider toolCallbackProvider;

    /**
     * 带聊天记忆流式返回
     *
     * @param accessKey 聊天访问key，每次打开聊天页面重置
     * @param inputInfo 聊天输入内容
     * @param docIds    参考文档ID，多个用英文','号隔开
     * @return
     */
/*    @GetMapping("/memoryStreamWithApi1")
    public Flux<ServerSentEvent<ChatDto>> memoryStreamWithApi(String accessKey, String inputInfo, String docIds, String token, String chatType) {
        if(StrUtil.isBlank(token)){
            ChatDto customResponse = new ChatDto("", ChatUtil.CHAT_TYPE_AI, ChatTYpe.TEXT.getType(),"未提供token", new ArrayList<>());
            return Flux.just(ServerSentEvent.<ChatDto>builder().data(customResponse).build());
        }
        SendMsgDto sendMsgDto = SendMsgDto.builder()
                .accessKey(accessKey)
                .inputInfo(inputInfo)
                .docIds(docIds)
                .chatType(chatType)
                .userId(TokenUtil.getCurrentUserId())
                .chatType(chatType)
                .build();
        return chatService.memoryStreamWithApi(sendMsgDto);
    }*/



    @GetMapping("/memoryStreamWithApi")
    public  Flux<ServerSentEvent<ChatDto>> ollamaChat(String accessKey, String inputInfo, String docIds, String token, String chatType) {
        SendMsgDto sendMsgDto = SendMsgDto.builder()
                .accessKey(accessKey)
                .inputInfo(inputInfo)
                .docIds(docIds)
                .chatType(chatType)
                .userId(TokenUtil.getCurrentUserId())
                .chatType(chatType)
                .build();

        StringBuilder fullResponse = new StringBuilder();
        return ChatClient.builder(ollamaChatModel)
                .defaultSystem("你是一个系统业务专家，回答尽量使用中文。") //默认提示词
                .defaultAdvisors(
                        new MessageChatMemoryAdvisor(new InMemoryChatMemory()))
                .defaultTools(toolCallbackProvider.getToolCallbacks())
                .build()
                .prompt()
                .user(sendMsgDto.getInputInfo())
                .advisors(advisor -> advisor.param(CHAT_MEMORY_CONVERSATION_ID_KEY, sendMsgDto.getAccessKey()).param(CHAT_MEMORY_RETRIEVE_SIZE_KEY, 5))
                .stream()
                .chatResponse()
                .map(response -> {
                    // 创建自定义响应对象
                    ChatDto customResponse = new ChatDto(sendMsgDto.getMsgId(), ChatUtil.CHAT_TYPE_AI, ChatTYpe.TEXT.getType(), response.getResult().getOutput().getText(), new ArrayList<>());
                    fullResponse.append(response.getResult().getOutput().getText());
                    return ServerSentEvent.<ChatDto>builder()
                            .data(customResponse)
                            .build();
                })
                .concatWith(Flux.just(
                        ServerSentEvent.<ChatDto>builder()
                                .data(new ChatDto(sendMsgDto.getMsgId(), ChatUtil.CHAT_TYPE_AI, ChatTYpe.TEXT.getType(),"[DONE]", new ArrayList<>())) // 结束标志
                                .build()
                )).doOnComplete(() -> {
                    // 流结束后异步保存完整响应到数据库
                    charRecordService.saveCharRecord(fullResponse.toString(), sendMsgDto);
                });



//        ChatClient chatClient = ChatClient.builder(ollamaChatModel)
//                .defaultTools(toolCallbackProvider.getToolCallbacks())
//                .build();
//        ChatClient.CallResponseSpec call = chatClient.prompt(sendMsgDto.getInputInfo()).call();
//        String content = call.content();
//        return null;
    }


/*    *//**
     *  获取匹配到的文件列表
     * @param sendMsgDto
     * @return
     *//*
    @PostMapping("/matchtoFiles")
    public Result matchtoFiles(@RequestBody SendMsgDto sendMsgDto) {
        List<DocVtsDto> matchtoFiles = chatService.getMatchtoFiles(sendMsgDto);
        return Result.OK(matchtoFiles);
    }*/


    @PostMapping("/getCharSession")
    public Result getCharRecord() {







        String url = "https://service.canalmuseum.net:8443/apiA/booking/getBookingData3?openid=oZiV06-dCtvKL5Xv3LOF6FoKdCTg&date=2025-05-09";
        String token = "ebdc155d-a11a-456e-9764-dc6efaaeea6e";
        String sign = "JHYmLHRycJ9XHx146492tqpVjplvc4BZe2eo3pwzkovaMNFOJLy9WLLAcjB3kie";
        String userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36 MicroMessenger/7.0.20.1781(0x6700)";
        String authorization = "bearer undefined";
        String referer = "https://servicewechat.com/wx281a8b44bb2dc0d6/101/page-frame.html";
        String xwebXhr = "1";
        String secFetchDest = "empty";
        String secFetchMode = "cors";
        String secFetchSite = "cross-site";
        String connection = "keep-alive";
        String host = "service.canalnuseum.net:8443";


        //{"msg":"操作成功","code":200,"openid":"oZiV06-dCtvKL5Xv3LOF6FoKdCTg","token":"ebdc155d-a41a-456e-9764-dc6efaaeaa6e"}
//        https://service.canalmuseum.net:8443/apiA/wx/code2Session?code=0a3Zfoll2rjcyf4kEVkl26fbWd3Zfol4

        HttpResponse response = HttpRequest.get(url)
                .header("openid", "oZiV06-dCtvKL5Xv3LOF6FoKdCTg")
                .header("date", "2025-05-10")
                .header("token", "ebdc155d-a41a-456e-9764-dc6efaaeaa6e")
                .header("sign", "TespYdv/IJWE9VHEzH46r/3PyAYNQN2yfXXVN4g1zbjdwaYmXFWC9CmmUCGDGdC+")
//                .header("sign", null)
                .header("user-agent", userAgent)
                .header("authorization", authorization)
                .header("referer", referer)
                .header("x-web-xhr", xwebXhr)
                .header("sec-fetch-dest", secFetchDest)
                .header("sec-fetch-mode", secFetchMode)
                .header("sec-fetch-site", secFetchSite)
                .header("connection", connection)
                .header("host", host)
                .execute();
        if (response.getStatus() == 200) {
            String body = response.body();
            log.info("body={}", body);
        }


        List<UserSession> list = charRecordService.getCharSession();
        return Result.OK(ChatUtil.groupByCreateTime(list));
    }


    @GetMapping("/getCharRecordById")
    public Result getCharRecordById(String accessKey) {
        List<ChatSessionRecord> list = charRecordService.getCharRecordById(accessKey);
        return Result.OK(ChatUtil.toChatSessionRecord(list));
    }


    @GetMapping("/grabBaiduHotNews")
    public Result grabBaiduHotNews() {
        List<News> news = ChatUtil.grabBaiduHotNews();
        //取前四个热钱进行展示
        if(news.size()>4){
            news = news.subList(0,4);
        }
        return Result.OK(news);
    }

}
